// LowLevelJNI.cpp : Defines the entry point for the DLL application.
//

//#include "stdafx.h"
#include <jni.h>
#include "UnitConcatJNI.h"
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <afx.h>
//
#include "Psola.h"
#include "TextHandle.h"
using namespace std;

CString DEST = "C:\\wav\\result.wav";
CString path = "C:\\wav\\FormOfSPESIALS\\";
CString DEST_LOC = "C:\\wav\\";
const char * str;
const char * nameWavFile;
string line;
CString cs, csLine, csFound, csFileName, csStartIndex, csEndIndex, csSylPhContent, fileLocation; // cs la doan van ban can tong hop
int startIndex, endIndex, isWritten = 0,count=0;
CString fullPathOfWavFile;

JNIEXPORT void JNICALL Java_UnitConcatJNI_UnitConcatenative (JNIEnv *env, jobject obj, jstring location, jstring nameOfWavFile)
{	
	jboolean isCopy;
	str = (*env).GetStringUTFChars(location,&isCopy);
	nameWavFile = (*env).GetStringUTFChars(nameOfWavFile,&isCopy);
	fullPathOfWavFile =DEST_LOC + nameWavFile + ".wav";
	//ReadHalfSylDB();
	ReadText();
	return;
}

void ReadText()
{	
	/*
	ifstream myfile (str);
	ifstream myfile ("E:\\Users\\thaodv_bkit\\Documents\\NetBeansProjects\\TTS_Lowlevel_SVN\\SelectedLPhrs.txt");
	printf("%s",str);

	if (myfile.is_open())
	{
		while ( myfile.good() )
		{
			getline (myfile,line);			
			ReadLine();
		}
		myfile.close();
	}

	else cout << "Unable to open file"; 
	*/
	/*
	CFile cf_object;
	//cf_object.Open("E:\\Users\\thaodv_bkit\\Documents\\NetBeansProjects\\TTS_Lowlevel_SVN\\SelectedLPhrs.txt", CFile::modeRead);
	cf_object.Open(str,CFile::modeRead);
	int length = cf_object.GetLength(); //data length
	char *dataBuffer = new char[length];
	cf_object.Read(dataBuffer,length);

	CString csText;
	csText.Format("%s",dataBuffer);
	cout<<str<<endl;
	cout<<csText<<endl;
	*/
		FILE *fp;
		if( (fp = fopen(str, "rt")) == NULL ) 
		{
			cout << "File could not be opened " << str<<endl;
			
			// lay tham so dau tien truyen vao la ten file text can tong hop; thaodv-070111
			// neu thanh cong tra ve con tro file fp; thaodv-070111
		}

		fseek(fp,0,SEEK_SET); // tro vao dau file; 
		fseek(fp,0,SEEK_END); // tro vao cuoi file thaodv 170211
		
		long lSizeOfFile = ftell(fp);
		cout << "size: "<<lSizeOfFile<<endl;
		fseek(fp,0,SEEK_SET);
		
		char *Buff;
		Buff = new char[lSizeOfFile+1];
			
		fread(Buff,lSizeOfFile,1,fp);
		// doc tu fp, luu vao mot vung nho do con tro Buff tro toi kich thuoc lSizeOfFile*1 bytes thaodv 170211
		Buff[lSizeOfFile] = NULL;

		
		cs.Format("%s",Buff);//+3);// convert from char array to CString thaodv 170211
		cs.TrimLeft();
		cs.TrimRight();
		//cs.MakeLower();
		
		delete[] Buff;
		fclose(fp);		
		cout << str <<endl;		
		ReadLine();
		FixWavFile();
}

///////////////////////
void ReadLine()
{
	int beginIndex = 0, foundIndex, length;
	length = cs.GetLength();
	while(beginIndex+1 < length)
	{
		foundIndex = cs.Find("\n",beginIndex);
		if(foundIndex == -1) break;
		csLine = cs.Mid(beginIndex,foundIndex-beginIndex);
		beginIndex = foundIndex +1;
		//printf("%s \n",csLine);
		ParseLine();
	}
}
////////////////////////
void ParseLine()
{
	int beginIndex = 0, foundIndex =0;
	
		//1 PTP00003_000.wav 107360 118643 SILS
		foundIndex = csLine.Find(" ",beginIndex);
		csFound = csLine.Mid(beginIndex,foundIndex-beginIndex);
		beginIndex = foundIndex +1;
		///
		foundIndex = csLine.Find(" ",beginIndex);
		csFileName = csLine.Mid(beginIndex,foundIndex-beginIndex);
		beginIndex = foundIndex +1;
		///
		foundIndex = csLine.Find(" ",beginIndex);
		csStartIndex = csLine.Mid(beginIndex,foundIndex-beginIndex);
		startIndex = atoi(csStartIndex);
		beginIndex = foundIndex +1;
		///
		foundIndex = csLine.Find(" ",beginIndex);
		csEndIndex = csLine.Mid(beginIndex,foundIndex-beginIndex);
		beginIndex = foundIndex +1;
		endIndex = atoi(csEndIndex);
		///		
		csSylPhContent = csLine.Mid(beginIndex,csLine.GetLength()-beginIndex);		
	
	printf("here: %s : %s : %d : %d : %s : \n",csFound, csFileName, startIndex, endIndex, csSylPhContent);
	if(csFound.Compare("1")==0)
	{
		WriteWavFile();
	}	else if (csFound.Compare("false")==0)
	{
		CString csInput;
		csInput.Format("%s",csSylPhContent);
		//HalfSylSyn(csInput); //bien truyen vao la csSylPhContent
	}

	
	
}

////
void WriteWavFile()
{
	char ChunkID[4], Format[4], Subchunk1ID[4],Subchunk2ID[4];
	int ChunkSize,Subchunk1Size =0, SampleRate, ByteRate,Subchunk2Size=0;
	short AudioFormat, NumChannels, BlockAlign, BitsPerSample = 16;
	short *Data; // 2 bytes
	int sizeOfHeader = 44;
	 int numOfBytesToRead;
	numOfBytesToRead = 2*(endIndex - startIndex);
	//Data=new short [numOfBytesToRead/(16/8)];
	int s = numOfBytesToRead/(16/8);
	 
	
	fileLocation = path +  csFileName;
	
	FILE *fhandle=fopen(fileLocation,"rb");
	//
	fseek(fhandle, 0, SEEK_SET);
	

	if(isWritten == 0)
	{
		isWritten ++;
		//neu file chua co du lieu
		//doc file lay du lieu	
		fread(ChunkID,1,4,fhandle);
		fread(&ChunkSize,4,1,fhandle);
		fread(Format,1,4,fhandle);
		fread(Subchunk1ID,1,4,fhandle);
		fread(&Subchunk1Size,4,1,fhandle);
		fread(&AudioFormat,2,1,fhandle);
		fread(&NumChannels,2,1,fhandle);
		fread(&SampleRate,4,1,fhandle);
		fread(&ByteRate,4,1,fhandle);
		fread(&BlockAlign,2,1,fhandle);
		fread(&BitsPerSample,2,1,fhandle);
		fread(&Subchunk2ID,1,4,fhandle);
		fread(&Subchunk2Size,4,1,fhandle);
		// tro toi vi tri startIndex
		fseek(fhandle,sizeOfHeader + (BitsPerSample/8)*startIndex, SEEK_SET);
		//
		Subchunk2Size = (endIndex - startIndex)*NumChannels*BitsPerSample/8;	
		Data=new short [(endIndex-startIndex)*NumChannels]; // Create an element for every sample
	
		fread(Data,BitsPerSample/8,Subchunk2Size/(BitsPerSample/8),fhandle); // Reading raw audio data
	
		fclose(fhandle);
		// ket thuc doc file
	
		ChunkSize = 4 + (8+Subchunk1Size) + (8+Subchunk2Size);
		//bat dau ghi file		
		FILE *fhandleWrite = fopen(fullPathOfWavFile , "wb");
		
		fwrite(ChunkID,1,4,fhandleWrite);
		fwrite(&ChunkSize,4,1,fhandleWrite);
		fwrite(Format,1,4,fhandleWrite);
		fwrite(Subchunk1ID,1,4,fhandleWrite);
		fwrite(&Subchunk1Size,4,1,fhandleWrite);
		fwrite(&AudioFormat,2,1,fhandleWrite);
		fwrite(&NumChannels,2,1,fhandleWrite);
		fwrite(&SampleRate,4,1,fhandleWrite);
		fwrite(&ByteRate,4,1,fhandleWrite);
		fwrite(&BlockAlign,2,1,fhandleWrite);
		fwrite(&BitsPerSample,2,1,fhandleWrite);
		fwrite(&Subchunk2ID,1,4,fhandleWrite);
		fwrite(&Subchunk2Size,4,1,fhandleWrite);	
		fwrite(Data,BitsPerSample/8,Subchunk2Size/(BitsPerSample/8),fhandleWrite);	
		fclose(fhandleWrite);
		cout << "ket thuc ghi file lan dau" <<endl;
		

	} 
	else 	{
		cout<<"chay toi day roi "<<endl;
		FILE *fhandleWrite = fopen(fullPathOfWavFile, "a+b");
		fseek(fhandle, 22, SEEK_SET);
		fread(&NumChannels,2,1,fhandle);
		cout << "NumChannels: "<< NumChannels<<endl;
		//neu file da co du lieu
		// tro toi vi tri startIndex
		fseek(fhandle,sizeOfHeader + (BitsPerSample/8)*startIndex, SEEK_SET);		
		Data=new short [(endIndex-startIndex)*NumChannels]; // Create an element for every sample
		fread(Data,BitsPerSample/8,(endIndex - startIndex)*NumChannels,fhandle); // Reading raw audio data
		fclose(fhandle);
		// ket thuc doc file
		Subchunk2Size += numOfBytesToRead;
		ChunkSize = 4 + (8+Subchunk1Size) + (8+Subchunk2Size);
		//bat dau ghi file
		//fseek(fhandleWrite, 4, SEEK_SET);
		//fwrite(&ChunkSize,4,1,fhandleWrite);
		//fseek(fhandleWrite, 40, SEEK_SET);
		//fwrite(&Subchunk2Size,4,1,fhandle);
		fseek(fhandleWrite,0, SEEK_END);
		fwrite(Data,BitsPerSample/8,Subchunk2Size/(BitsPerSample/8),fhandleWrite);
		fclose(fhandleWrite);		
	}
	
}

///
void FixWavFile()
{
	char ChunkID[4], Format[4], Subchunk1ID[4],Subchunk2ID[4];
	int ChunkSize,Subchunk1Size =0, SampleRate, ByteRate,Subchunk2Size=0;
	short AudioFormat, NumChannels, BlockAlign, BitsPerSample = 16;
	short *Data; // 2 bytes
	int sizeOfHeader = 44;
	FILE *fhandle=fopen(fullPathOfWavFile,"rb");	
	fseek(fhandle,0,SEEK_SET); // tro vao dau file; 
	fseek(fhandle,0,SEEK_END); // tro vao cuoi file thaodv 170211
	long lSizeOfFile1 = ftell(fhandle);
	fseek(fhandle, 0, SEEK_SET);

		fread(ChunkID,1,4,fhandle);
		fread(&ChunkSize,4,1,fhandle);
		fread(Format,1,4,fhandle);
		fread(Subchunk1ID,1,4,fhandle);
		fread(&Subchunk1Size,4,1,fhandle);
		fread(&AudioFormat,2,1,fhandle);
		fread(&NumChannels,2,1,fhandle);
		fread(&SampleRate,4,1,fhandle);
		fread(&ByteRate,4,1,fhandle);
		fread(&BlockAlign,2,1,fhandle);
		fread(&BitsPerSample,2,1,fhandle);
		fread(&Subchunk2ID,1,4,fhandle);
		fread(&Subchunk2Size,4,1,fhandle);	
		Subchunk2Size = lSizeOfFile1 - sizeOfHeader;
		Data=new short [Subchunk2Size/(BitsPerSample/8)]; // Create an element for every sample
		fread(Data,BitsPerSample/8,Subchunk2Size/(BitsPerSample/8),fhandle); // Reading raw audio data
		fclose(fhandle);
		// ket thuc doc file	
		ChunkSize = 4 + (8+Subchunk1Size) + (8+Subchunk2Size);

		//////bat dau ghi file
		fhandle=fopen(fullPathOfWavFile,"wb");
		fwrite(ChunkID,1,4,fhandle);
		fwrite(&ChunkSize,4,1,fhandle);
		fwrite(Format,1,4,fhandle);
		fwrite(Subchunk1ID,1,4,fhandle);
		fwrite(&Subchunk1Size,4,1,fhandle);
		fwrite(&AudioFormat,2,1,fhandle);
		fwrite(&NumChannels,2,1,fhandle);
		fwrite(&SampleRate,4,1,fhandle);
		fwrite(&ByteRate,4,1,fhandle);
		fwrite(&BlockAlign,2,1,fhandle);
		fwrite(&BitsPerSample,2,1,fhandle);
		fwrite(&Subchunk2ID,1,4,fhandle);
		fwrite(&Subchunk2Size,4,1,fhandle);
		fwrite(Data,BitsPerSample/8,Subchunk2Size/(BitsPerSample/8),fhandle);

		fclose(fhandle);

}

////////
void HalfSylSyn(CString csPhContent)
{
	CMyDatabase myDB;
	

	
	// doc csdl ban am tiet, goi ham nay ngay tu ban dau
	char cBuff[256];
	GetCurrentDirectory(256,cBuff);  // lay thu muc hien tai, truyen vao cBuff ; thaodv-070111
		
	CTextHandle::CsDirectoryOfFile = cBuff;		
	// Database la HalfSyl.dat; thaodv-070111
	CTextHandle::CS_DBFileName = CTextHandle::CsDirectoryOfFile + '\\' + "HalfSyl.dat";

	
	if(!CPsola::DB_Open(CTextHandle::CS_DBFileName))
	{
		cout << "Database file could not be opened " << endl;
		//goi toi method cua CPsola class de mo file database; thaodv-070111
	}


	ofstream txtFile;
	txtFile.open("txt_MyDatabase.txt",ios::app);
	if (txtFile.is_open())
	  {
		//txtFile << "This is a line.\n";
		//txtFile << "This is another line.\n";
		txtFile <<csPhContent << "\n";
		txtFile.close();
		
	  }
	else cout << "Unable to open file";
	
	CPsola::CsNameOfWavFile		= "testJNI";
	CPsola::CsNameOfDebugFile	= CTextHandle::CsDirectoryOfFile + '\\'+ CPsola::CsNameOfWavFile + ".bug";
	CPsola::CsNameOfWavFile		= CTextHandle::CsDirectoryOfFile + '\\'+ CPsola::CsNameOfWavFile + ".wav";
	CPsola::nF0_Begin			= 210;
	CPsola::fSpeakingRate = 1.0f;
	
	CTextHandle txt;  // tao mot object cua TextHandle Class. thaodv-070111
	 if(!txt.ParseText(csPhContent)) { // goi method ParseText() cua TextHandle; thaodv-070111; neu khogn thanh cong thi bao loi
		cout<<"loi trong khi goi toi ParseText();"<<endl;
	}
	
}
///////////
